﻿using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

using RaisingStudio.SmallProgram.Library.Internal;

namespace RaisingStudio.SmallProgram.Library
{
    [SmallProgramType]
    public static class TextWindow
    {
        private static int _editableStartIndex = -1;
        private static TextBox _textBox;
        private static int _totalTextLength = 0;
        private static bool _windowVisible = false;

        public static Primitive BackgroundColor
        {
            get
            {
                VerifyAccess();
                return (Primitive)SmallProgramApplication.InvokeWithReturn(delegate
                {
                    return ((SolidColorBrush)_textBox.Background).Color.ToString();
                });
            }
            set
            {
                VerifyAccess();
                SmallProgramApplication.BeginInvoke(delegate
                {
                    _textBox.Background = new SolidColorBrush(ColorConverter.GetColor((string)value));
                });
            }
        }

        public static Primitive CursorLeft
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public static Primitive CursorTop
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public static FrameworkElement Element
        {
            get
            {
                return _textBox;
            }
        }

        public static Primitive ForegroundColor
        {
            get
            {
                return "White";
            }
            set
            {
            }
        }

        public static Primitive Left
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public static Primitive Title
        {
            get
            {
                return GraphicsWindow.Title;
            }
            set
            {
                GraphicsWindow.Title = value;
            }
        }

        public static Primitive Top
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public static void Initialize()
        {
            TextBox box = new TextBox();
            box.Background = new SolidColorBrush(Colors.Black);
            box.AcceptsReturn = true;
            box.BorderBrush = new SolidColorBrush(Color.FromArgb(0xff, 0x99, 0x99, 0x99));
            box.BorderThickness = new Thickness(1.0);
            box.Foreground = new SolidColorBrush(Colors.White);
            box.Width = 640.0;
            box.Height = 160.0;
            box.CaretBrush = new SolidColorBrush(Colors.White);
            box.Visibility = Visibility.Collapsed;
            box.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            box.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
            box.IsReadOnly = true;
            _textBox = box;
        }

        public static void Clear()
        {
            _totalTextLength = 0;
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.Text = "";
                _editableStartIndex = -1;
            });
        }

        private static void VerifyAccess()
        {
            if (!_windowVisible)
            {
                Show();
            }
        }

        public static void Show()
        {
            SmallProgramApplication.BeginInvoke(delegate
            {
                _windowVisible = true;
                _textBox.Visibility = Visibility.Visible;
            });
        }

        public static void Hide()
        {
            SmallProgramApplication.BeginInvoke(delegate
            {
                _windowVisible = false;
                _textBox.Visibility = Visibility.Collapsed;
            });
        }

        public static void Pause()
        {
            VerifyAccess();
            WriteLine("Press any key to continue...");
            PauseWithoutMessage();
        }

        public static void PauseIfVisible()
        {
            if (_windowVisible)
            {
                Pause();
            }
        }

        public static void PauseWithoutMessage()
        {
            VerifyAccess();
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            KeyEventHandler handler = null;
            handler = delegate(object o, KeyEventArgs e)
            {
                _textBox.KeyDown -= handler;
                manualResetEvent.Set();
                _textBox.IsReadOnly = true;
                e.Handled = true;
            };
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.IsReadOnly = false;
                _textBox.KeyDown += handler;
            });
            manualResetEvent.WaitOne();
        }

        public static Primitive Read()
        {
            VerifyAccess();
            int startIndex = _totalTextLength;
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            KeyEventHandler handler = null;
            string text = "";
            handler = delegate(object o, KeyEventArgs e)
            {
                if (e.Key == Key.Enter)
                {
                    _textBox.KeyDown -= handler;
                    text = _textBox.Text.Substring(startIndex);
                    _totalTextLength += text.Length;
                    _textBox.SelectionStart = _totalTextLength;
                    _textBox.SelectedText = "\r\n";
                    _totalTextLength += 2;
                    _textBox.IsReadOnly = true;
                    manualResetEvent.Set();
                    e.Handled = true;
                }
                if (_textBox.SelectionStart < startIndex)
                {
                    e.Handled = true;
                }
                else if ((e.Key == Key.Back) && (_textBox.SelectionStart <= startIndex))
                {
                    e.Handled = true;
                }
            };
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.IsReadOnly = false;
                _textBox.Focus();
                _textBox.KeyDown += handler;
            });
            manualResetEvent.WaitOne();
            return text;
        }

        public static Primitive ReadKey()
        {
            VerifyAccess();
            int startIndex = _totalTextLength;
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            TextChangedEventHandler handler = null;
            string text = "";
            handler = delegate(object o, TextChangedEventArgs e)
            {
                _textBox.TextChanged -= handler;
                text = _textBox.Text.Substring(startIndex);
                _textBox.SelectionStart = _totalTextLength;
                _textBox.SelectionLength = text.Length;
                _textBox.SelectedText = "";
                _textBox.IsReadOnly = true;
                manualResetEvent.Set();
            };
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.IsReadOnly = false;
                _textBox.Focus();
                _textBox.TextChanged += handler;
            });
            manualResetEvent.WaitOne();
            return text;
        }

        public static Primitive ReadNumber()
        {
            VerifyAccess();
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            int startIndex = _totalTextLength;
            KeyEventHandler handler = null;
            string text = "";
            handler = delegate(object o, KeyEventArgs e)
            {
                int num = _textBox.SelectionStart - startIndex;
                bool flag = false;
                if (num >= 0)
                {
                    if ((e.Key == Key.Subtract) && (num == 0))
                    {
                        flag = true;
                    }
                    else if (e.Key == Key.Decimal)
                    {
                        if (!_textBox.Text.Substring(startIndex).Contains("."))
                        {
                            flag = true;
                        }
                    }
                    else if ((e.Key >= Key.D0) && (e.Key <= Key.D9))
                    {
                        flag = true;
                    }
                    else if ((e.Key == Key.Back) && (num > 0))
                    {
                        num--;
                        flag = true;
                    }
                }
                if (!flag)
                {
                    e.Handled = true;
                }
                if (e.Key == Key.Enter)
                {
                    _textBox.KeyDown -= handler;
                    text = _textBox.Text.Substring(startIndex);
                    _totalTextLength += text.Length;
                    _textBox.SelectionStart = _totalTextLength;
                    _textBox.SelectedText = "\r\n";
                    _totalTextLength += 2;
                    _textBox.IsReadOnly = true;
                    manualResetEvent.Set();
                    e.Handled = true;
                }
            };
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.IsReadOnly = false;
                _textBox.Focus();
                _textBox.KeyDown += handler;
            });
            manualResetEvent.WaitOne();
            if (text.Length == 0)
            {
                return new Primitive(0);
            }
            return new Primitive(text.ToString());
        }

        public static void Write(Primitive data)
        {
            VerifyAccess();
            int _selectionStart = _totalTextLength;
            _totalTextLength += ((string)data).Length;
            SmallProgramApplication.BeginInvoke(delegate
            {
                _textBox.Select(_selectionStart, 0);
                _textBox.SelectedText = (string)data;
            });
        }

        public static void WriteLine(Primitive data)
        {
            Write(((string)data) + "\r\n");
        }
    }
}

